home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-03
/
imb9110.zip
/
BITLIST.BAS
< prev
next >
Wrap
BASIC Source File
|
1991-10-01
|
9KB
|
224 lines
'****************************************************
'* BITLIST.BAS - routines to manipulate bit lists *
'****************************************************
' $INCLUDE: 'BITLIST.BI'
CONST FALSE = 0, TRUE = NOT FALSE
CONST CPI = 2 ' # chars in 1 integer
CONST CS = 8 ' # bits in 1 character
FUNCTION blCreate (Size%)
'****************************************************
'* blCreate - create a bitlist *
'* *
'* INP: Size - number of bits in the list *
'* OUT: 'handle' of the new bitlist, NULL if *
'* the bitlist could not be created. *
'****************************************************
SHARED MAllocSpace$, MasterPointers$, FirstFree%
IF FirstFree% = 0 THEN
' this is the first allocation, no master pointers exist yet
MasterPointers$ = STRING$(2, 0)
FirstFree% = LEN(MasterPointers$) + 1
NextList% = (FirstFree% - 1) \ 2
mPtr% = FirstFree% - 2
ELSE
IF FirstFree% = LEN(MasterPointers$) + 1 THEN
' normal allocation, no master pointers have been freed
MasterPointers$ = MasterPointers$ + STRING$(2, 0)
FirstFree% = LEN(MasterPointers$) + 1
NextList% = (FirstFree% - 1) \ 2
mPtr% = FirstFree% - 2
ELSE
' re-use a previously freed master pointer
NextList% = (FirstFree% + 1) \ 2
mPtr% = FirstFree%
FirstFree% = ABS(CVI(MID$(MasterPointers$, mPtr%, 2)))
END IF
END IF
lPtr% = LEN(MAllocSpace$) + 1
MAllocSpace$ = MAllocSpace$ + STRING$(((Size%+CS-1)\CS+CPI),0)
MID$(MAllocSpace$, lPtr%, 2) = MKI$(Size%)
MID$(MasterPointers$, mPtr%, 2) = MKI$(lPtr%)
blCreate = NextList%
END FUNCTION
SUB blDestroy (BitList%)
'****************************************************
'* blDestroy - destroy a bitlist *
'* *
'* INP: BitList% - 'handle' to bitlist to destroy *
'****************************************************
SHARED MAllocSpace$, MasterPointers$, FirstFree%
' de-reference the bitlist handle
drBl% = CVI(MID$(MasterPointers$, BitList%*2-1, 2))
' Adjust the master pointers that come after the master pointer that
' points to the bitlist being destroyed.
' (if this was not the bitlist pointed to by the last master pointer
' in the master pointer list)
IF BitList% * 2 < LEN(MasterPointers$) THEN
Adjustment% = (CVI(MID$(MAllocSpace$, drBl%, 2)) + CS - 1) \ CS + CPI
FOR aBl% = BitList% + 1 TO LEN(MasterPointers$) \ 2
mPtr% = CVI(MID$(MasterPointers$, aBl% * 2 - 1, 2))
IF mPtr% > 0 THEN
' (pointers with values less than 1 are in the free list)
MID$(MasterPointers$, aBl% * 2 - 1, 2) = MKI$(mPtr% - Adjustment%)
END IF
NEXT aBl%
END IF
' Do garbage collection on the master pointer list
mPtr% = BitList% * 2 - 1
MID$(MasterPointers$, mPtr%, 2) = MKI$(0)
IF mPtr% + 1 = LEN(MasterPointers$) THEN
' this is the master pointer at the end of the list,
' so just get rid of it. We'll allocate it again if we need to.
MasterPointers$ = LEFT$(MasterPointers$, mPtr% - 1)
ELSE
IF FirstFree% > LEN(MasterPointers$) THEN
' this is the first master pointer we've freed
FirstFree% = mPtr%
ELSE
' add this master pointer to the free list
Prev% = 0: Done% = FALSE: WorkPtr% = FirstFree%
DO UNTIL Done%
' look for the end of the list
NextPtr% = ABS(CVI(MID$(MasterPointers$, WorkPtr%, 2)))
IF NextPtr% = 0 THEN
' we've found the end of the free list
' set this node to pint to the master pointer we just freed
MID$(MasterPointers$, WorkPtr%, 2) = MKI$(-mPtr%)
Done% = TRUE
ELSE
' follow the link
WorkPtr% = NextPtr%
END IF
LOOP
END IF
END IF
' reclaim the space used by the list being destroyed
listLen% = CVI(MID$(MAllocSpace$, drBl%, 2))
SubStrLen% = (listLen% + CS - 1) \ CS + CPI
Front$ = LEFT$(MAllocSpace$, drBl% - 1)
RearStart% = drBl% + SubStrLen%
Rear$ = MID$(MAllocSpace$, RearStart%, LEN(MAllocSpace$) - RearStart% + 1)
MAllocSpace$ = Front$ + Rear$: Front$ = "": Rear$ = ""
END SUB
FUNCTION blGetBit (bl%, BitNum%)
'****************************************************
'* blGetBit - return current bit state *
'* *
'* INP: bl% - 'handle' to bitlist of interest *
'* BitNum% - the bit number of interest *
'* OUT: FALSE is bit is off or out of range, *
'* TRUE otherwise. *
'****************************************************
SHARED MAllocSpace$, MasterPointers$, FirstFree%
' de-reference the bitlist handle
drBl% = CVI(MID$(MasterPointers$, bl%*2-1, 2))
IF BitNum% >= CVI(MID$(MAllocSpace$, drBl%, 2)) THEN
fRes% = FALSE
ELSE
ByteNum% = BitNum% \ 8 + CPI
BitNum% = BitNum% MOD 8
fRes% = ASC(MID$(MAllocSpace$, drBl%+ByteNum%, 1)) AND 2 ^ BitNum%
END IF
blGetBit = fRes%
END FUNCTION
FUNCTION blSetBit (bl%, BitNum%, State%)
'****************************************************
'* blSetBit - return current bit state *
'* *
'* INP: bl% - 'handle' to bitlist of interest *
'* BitNum% - the bit number of interest *
'* State% - the new bit state *
'* OUT: TRUE on error, FALSE otherwise *
'****************************************************
SHARED MAllocSpace$, MasterPointers$, FirstFree%
' de-reference the bitlist handle
drBl% = CVI(MID$(MasterPointers$, bl%*2-1, 2))
IF BitNum% >= CVI(MID$(MAllocSpace$, drBl%, 2)) THEN
fRes% = TRUE
ELSE
ByteNum% = BitNum% \ 8 + CPI
BitNum% = BitNum% MOD 8
Mask% = 2 ^ BitNum%
IF State% THEN
MID$(MAllocSpace$, drBl%+ByteNum%, 1) = _
CHR$(ASC(MID$(MAllocSpace$, drBl%+ByteNum%, 1)) OR Mask%)
ELSE
MID$(MAllocSpace$, drBl%+ByteNum%, 1) = _
CHR$(ASC(MID$(MAllocSpace$, drBl%+ByteNum%, 1)) _
AND ((NOT Mask%) AND &HFF))
END IF
fRes% = FALSE
END IF
blSetBit = fRes%
END FUNCTION
FUNCTION blListOp (Op%, bl1%, bl2%)
'****************************************************
'* blListOp - perform a list operation *
'* *
'* INP: Op% - operation code to perform: *
'* blUNION, blINTERSECT, blCLEAR *
'* blCOPY, blSET, blINVERT *
'* bl1% - bitlist #1 *
'* bl2% - bitlist #2 (or 0 if no 2nd bitlist *
'* as for blCLEAR, blSET & blINVERT *
'* *
'* OUT: TRUE if UNION or INTERSECT or COPY detect *
'* that the lists are different sizes, *
'* FALSE otherwise. *
'****************************************************
SHARED MAllocSpace$, MasterPointers$, FirstFree%
' de-reference the bitlist handles
drBl1% = CVI(MID$(MasterPointers$, bl1%*2-1, 2))
IF bl2% <> 0 THEN
drBl2% = CVI(MID$(MasterPointers$, bl2%*2-1, 2))
END IF
IF Op% = blUNION OR Op% = blINTERSECT OR Op% = blCOPY THEN
IF CVI(MID$(MAllocSpace$, drBl1%, 2)) <> CVI(MID$(MAllocSpace$, drBl2%, 2)) _
THEN
fRes% = TRUE
EXIT FUNCTION
END IF
END IF
drBl1Len% = (CVI(MID$(MAllocSpace$, drBl1%, 2)) + CS-1)\CS
fRes% = FALSE
SELECT CASE Op%
CASE blCLEAR
MID$(MAllocSpace$, drBl1%+CPI, drBl1Len%) = STRING$(drBl1Len%, 0)
CASE blSET
MID$(MAllocSpace$, drBl1%+CPI, drBl1Len%) = STRING$(drBl1Len%, 255)
CASE blINVERT
FOR I%=CPI TO drBl1Len%+CPI-1
MID$(MAllocSpace$, drBl1%+I%, 1) = _
CHR$((NOT ASC(MID$(MAllocSpace$, drBl1%+I%, 1)) AND &HFF))
NEXT I%
CASE blUNION
FOR I%=CPI TO drBl1Len%+CPI-1
MID$(MAllocSpace$, drBl1%+I%, 1) = _
CHR$(ASC(MID$(MAllocSpace$, drBl1%+I%, 1)) _
OR ASC(MID$(MAllocSpace$, drBl2%+I%, 1)))
NEXT I%
CASE blINTERSECT
FOR I%=CPI TO drBl1Len%+CPI-1
MID$(MAllocSpace$, drBl1%+I%, 1) = _
CHR$(ASC(MID$(MAllocSpace$, drBl1%+I%, 1)) _
AND ASC(MID$(MAllocSpace$, drBl2%+I%, 1)))
NEXT I%
CASE blCOPY
MID$(MAllocSpace$, drBl1%+CPI, drBl1Len%) = _
MID$(MAllocSpace$, drBl2%+CPI, drBl1Len%)
CASE ELSE
fRes% = TRUE
END SELECT
blListOp = fRes%
END FUNCTION